package commander;

import java.io.File;
import java.io.IOException;
import java.util.Objects;

import core.*;
import gitobject.Commit;
import gui.GUI;
import repository.Repository;


public class CLI {

	/**
	 * Command 'jit init'
	 * @param args
	 * @throws IOException
	 */
	public static void jitInit(String[] args) throws IOException {
		String path = "";
		if(args.length <= 2) {
			path = new File(".").getCanonicalPath();
			JitInit.init(path);
		}else if(args[2].equals("-help")){ //see help
			System.out.println("usage: jit init [<path>] [-help]\r\n" +
					"\r\n" +
					"jit init [<path>]:	Create an empty jit repository or reinitialize an existing one in the path or your default working directory.");
		}else {
			path = args[2];
			if(!new File(path).isDirectory()) { //if the working path input is illegal
				System.out.println(path + "is not a legal directory. Please init your reposiroty again. See 'jit init -help'.");
			}else {
				JitInit.init(path);
			}
		}
	}

	/**
	 * Command 'jit hash'
	 * @param args
	 * @throws IOException
	 */
	public static void jitHash(String[] args) throws IOException {
		String path = "";
		if(args.length <= 2) { //get default working path
			path = new File(".").getCanonicalPath();
			JitHash.hash(path);
		}else if(args[2].equals("-help")){ //see help
			System.out.println("usage: jit hash [<filename>] [-help]\r\n" +
					"\r\n" +
					"jit hash [<filename>]:	Hash the jit repository.");
		}else {
			path = args[2];
			JitHash.hash(path);
		}
	}

	/**
	 * Command 'jit add'
	 * @param args
	 * @throws IOException
	 */
	public static void jitAdd(String[] args) throws IOException {
		String path = "";
		if(args.length <= 2) { //get default working path
			path = new File(".").getCanonicalPath();
			JitAdd.add(path);
		}else if(args[2].equals("-help")){ //see help
			System.out.println("usage: jit add [<filename>] [-help]\r\n" +
					"\r\n" +
					"jit add [<filename>]:	Add the file into index.");
		}else {
			path = args[2];
			JitAdd.add(path);
		}
	}

	/**
	 * Command 'jit commit'
	 * @param args
	 * @throws IOException
	 */
	public static void jitCommit(String[] args) throws IOException {
		String message = "";
		if(args.length <= 3) { //get default working path
			JitCommit.commit(message);
		}else if(args[3].equals("-help")){ //see help
			System.out.println("usage: jit commit -m [<message>] [-help]\r\n" +
					"\r\n" +
					"jit commit -m [<message>]:	Add the file into index.");
		}else {
			message = args[3];
			JitCommit.commit(message);
		}
	}

	/**
	 * Command 'jit rm'
	 * @param args
	 * @throws IOException
	 */
	public static void jitRm(String[] args) throws IOException {
		String path = "";
		if(args.length <= 2) { //get default working path
			path = new File(".").getCanonicalPath();
			JitRm.rm(path);
		}else if(args[2].equals("-help")){ //see help
			System.out.println("usage: jit rm [<filename>] [-help]\r\n" +
					"\r\n" +
					"jit rm [<filename>]:	Add the file into index.");
		}else {
			path = args[2];
			JitRm.rm(path);
		}
	}

	/**
	 * Command 'jit log'
	 * @param args
	 * @throws IOException
	 */
	public static void jitLog(String[] args) throws IOException {
		if(args.length <= 2) { //get default working path
			JitLog.log();
		}else if(args[2].equals("-help")){ //see help
			System.out.println("usage: jit log [-help]\r\n" +
					"\r\n" +
					"jit log:	Add the file into index.");
		}
	}

	/**
	 * Command 'jit reset'
	 * @param args
	 * @throws IOException
	 */
	public static void jitReset(String[] args) throws IOException {
		String mode = "";
		String commit = "";
		if(args.length <= 2) { //get default reset mode
			JitReset.reset("--mixed", commit);
		}else if(args[2].equals("-help")){ //see help
			System.out.println("usage: jit reset [<mode>] [<commit>] [-help]\r\n" +
					"\r\n" +
					"jit reset [<mode>] [<commit>]:	Add the file into index.");
		}else {
			mode = args[2];
			commit = args[3];
			JitReset.reset(mode, commit);
		}
	}
	

	/**
	 * Command 'jit branch'
	 * @param args
	 * @throws IOException
	 */
	public static void jitBranch(String[] args) throws IOException {
		String branceName = "";
		if(args.length <= 2) {  // 输出所有的分支
			JitBranch.printBranch();
		}
		else if(args.length == 3){ // 长度为三，可以是help也可以是新建分支
			if (args[2].equals("-helps")){  // jit branch的help内容
				System.out.println("usage: jit branch [<branchName>] [-help]\r\n" +
						"\r\n" +
						"jit branch [<branchName>]:	Add the branchName into index.");
			}
			else {
				branceName = args[2];
				JitBranch.newBranch(branceName);
			}
		}
		else if (args.length == 4 && args[2].equals("-d")){
			JitBranch.deleteBranch(args[3]);
		}
		else{  // 此时没有任何branch方法，提示输入jit branch -helps 获取正确格式
			System.out.println("please make sure the usage you input is correct " +
					"and you can get help by input 'jit branch -help'");
		}
	}

	/**
	 * Command 'jit checkout'
	 * @param args
	 * @throws IOException
	 */
	public static void jitCheckout(String[] args) throws IOException {
		String branchName = "";
		if (args.length == 3 && args[2].equals("-help")){
			System.out.println("usage: jit checkout [<branchName>] [-help]\r\n" +
					"\r\n" +
					"jit checkout -d [<branchName>]:	Add the branchName into index.");
		}
		else if(args.length == 3) {  // 输出所有的分支
			branchName = args[2];
			JitCheckout.checkout(branchName);
		}
		else if (args.length == 4 && args[2].equals("-d")){
			branchName = args[3];
			JitCheckout.checkoutB(branchName);
		}
		else{
			System.out.println("please make sure the usage you input is correct " +
					"and you can get help by input 'jit checkout -help'");
		}

	}
	
	/**
	 * Command 'jit config'
	 * @param args
	 * @throws IOException
	 */
	public static void jitConfig(String[] args) throws IOException {
		String mode = "";
		String object = "";
		String name = "";
		if(args.length == 4) {
			if(Objects.equals(args[2], "user.name") || Objects.equals(args[2], "user.email")) {
				mode = "--local";
				object = args[2].split(".")[1];
				name = args[3];
			}
			else {
				for(String item: args) {
					System.out.print(item + " ");
				}
				System.out.println("is not a legal command. Please check your command again. See 'jit config -help'.");
			}
		}
		else if(args.length < 4) {
			for(String item: args) {
				System.out.print(item + " ");
			}
			System.out.println("is not a legal command. Please check your command again. See 'jit config -help'.");
		}
		else if(args[2].equals("-help")){ //see help
			System.out.println("usage: jit config [-help]\r\n" +
					"\r\n" +
					"jit config [<mode>] [<object>] [<name>]:	Create an empty jit repository or reinitialize an existing one in the path or your default working directory.");
		}
		else {
			mode = args[2];
			object = args[3];
			name = args[4];
			if(!Objects.equals(mode, "--global") || (!Objects.equals(object, "user.name") && !Objects.equals(object, "user.email"))) { //if the working path input is illegal
				for(String item: args) {
					System.out.print(item + " ");
				}
				System.out.println("is not a legal command. Please check your command again. See 'jit config -help'.");
			}else {
				JitConfig.config(mode, object, name);
			}
		}
	}
	
	/**
	 * Command 'jit gui'
	 * @param args
	 * @throws IOException
	 */
	public static void jitGui(String[] args) throws IOException {
		String path = "";
		if(args.length <= 2) {
			new GUI().initPanel();
		}else if(args[2].equals("-help")){ //see help
			System.out.println("usage: jit init [<path>] [-help]\r\n" +
					"\r\n" +
					"jit gui [<path>]:	Open a graphic user interface.");
		}else {
			path = args[2];
			if(!new File(path).isDirectory()) { //if the working path input is illegal
				System.out.println(path + "is not a legal directory. Please init your reposiroty again. See 'jit init -help'.");
			}else {
				new GUI(path).mainPanel();
			}
		}
	}

	public static void jitDiff(String[] args) throws IOException {
		if(args.length <= 2) { //get default reset mode
			JitDiff.diffWorkSpaceWithMap("indexMap");
		}else if(args[2].equals("-help")){ //see help
			System.out.println("usage: jit diff [<mode>] [<commit>] [<commit>] [-help]\r\n" +
					"\r\n" +
					"jit diff [<mode>] [<commit>] [<commit>]:	Add the file into index.");
		}else {
			if(args[2] == "--cached"){
				JitDiff.diffIndexAndCommit(Commit.getLastCommit());
			}
		}
	}

	public static void jitStatus(String[] args) throws IOException {
		if(args.length <= 2) { //get default reset mode
			JitStatus.status();
		}else if(args[2].equals("-help")){ //see help
			System.out.println("usage: jit status [-help]\r\n" +
					"\r\n" +
					"jit status :	status.");
		}
	}

	public static void jitCatFile(String[] args) throws IOException {
		if(!Objects.equals(args[2], "-help")) { //get default reset mode
			JitCatFile.catFile(args[3]);
		}else{ //see help
			System.out.println("usage: jit status [-help]\r\n" +
					"\r\n" +
					"jit cat-file :	cat-file.");
		}
	}
	/**
	 * Command 'jit help'.
	 */
	public static void jitHelp() {
		System.out.println("usage: jit [--version] [--help] [-C <path>] [-c name=value]\r\n" +
				"           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\r\n" +
				"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\r\n" +
				"           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\r\n" +
				"           <command> [<args>]\r\n" +
				"\r\n" +
				"These are common Jit commands used in various situations:\r\n" +
				"\r\n" +
				"start a working area\r\n" +
				"   init       Create an empty Jit repository or reinitialize an existing one\r\n" +
				"\r\n" +
				"work on the current change\r\n" +
				"   add        Add file contents to the index\r\n" +
				"   reset      Reset current HEAD to the specified state\r\n" +
				"   rm         Remove files from the working tree and from the index\r\n" +
				"\r\n" +
				"examine the history and state\r\n" +
				"   log        Show commit logs\r\n" +
				"   status     Show the working tree status\r\n" +
				"\r\n" +
				"grow, mark and tweak your common history\r\n" +
				"   branch     List, create, or delete branches\r\n" +
				"   checkout   Switch branches or restore working tree files\r\n" +
				"   commit     Record changes to the repository\r\n" +
				"   diff       Show changes between commits, commit and working tree, etc\r\n" +
				"   merge      Join two or more development histories together\r\n" +
				"\r\n" +
				"'jit help -a' and 'jit help -g' list available subcommands and some\r\n" +
				"concept guides. See 'jit help <command>' or 'jit help <concept>'\r\n" +
				"to read about a specific subcommand or concept.");
	}

	public static void main(String[] args) throws Exception {
		if(args.length <= 1 || args[1].equals("help")) {
			jitHelp();
		}else {
			if(args[1].equals("init")) {
				jitInit(args);
			}
			else{
				File checkRepository = new File(Repository.getGitDir());
				if(!(checkRepository.exists() && checkRepository.isDirectory())){
					System.out.println("fatal: not a jit repository: .jit");
				}
				else{
					JitMap.initial();
					switch (args[1]) {
						case "hash" -> jitHash(args);
						case "add" -> jitAdd(args);
						case "commit" -> jitCommit(args);
						case "rm" -> jitRm(args);
						case "log" -> jitLog(args);
						case "reset" -> jitReset(args);
						case "branch" -> jitBranch(args);
						case "checkout" -> jitCheckout(args);
						case "config" -> jitConfig(args);
						case "gui" -> jitGui(args);
						case "diff" -> jitDiff(args);
						default -> System.out.println("jit: " + args[1] + " is not a git command. See 'git help'.");
					}
				}
			}
		}
	}
}
